package org.mspring.platform.utils.http;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.HttpClients;
import org.mspring.platform.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * HttpClient的简单封装
 *
 * @author Gao Youbo
 * @since 2013年12月28日
 */
public class HttpUtils {

    public static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    /**
     * POST请求
     *
     * @param url 请求地址
     * @return
     * @throws IOException
     */
    public static HttpResponse post(String url) throws IOException {
        return post(url, null);
    }

    /**
     * POST请求
     *
     * @param url  请求URL
     * @param nvps 请求参数
     * @return
     * @throws java.io.IOException
     */
    public static HttpResponse post(String url, List<NameValuePair> nvps) throws IOException {
        return post(url, nvps, -1);
    }

    /**
     * POST请求
     *
     * @param url     请求地址
     * @param nvps    请求参数
     * @param timeout 超时时间
     * @return
     * @throws IOException
     */
    public static HttpResponse post(String url, List<NameValuePair> nvps, int timeout) throws IOException {
        return post(url, nvps, timeout, null);
    }

    /**
     * POST请求
     *
     * @param url     请求地址
     * @param nvps    请求参数
     * @param timeout 超时时间
     * @param referer referer
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static HttpResponse post(String url, List<NameValuePair> nvps, int timeout, String referer) throws ClientProtocolException, IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        if (timeout > 0) {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).setSocketTimeout(timeout).build();
            httpPost.setConfig(requestConfig);
        }
        if (nvps != null && !nvps.isEmpty()) {
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, DEFAULT_CHARSET));
        }
        if (StringUtils.isNotBlank(referer)) {
            httpPost.addHeader("referer", referer);
        }
        return httpClient.execute(httpPost);
    }

    public static HttpResponse post(String url, List<NameValuePair> nvps, Map<String, File> files) throws IOException {
        return post(url, nvps, files, -1);
    }

    public static HttpResponse post(String url, List<NameValuePair> nvps, Map<String, File> files, int timeout) throws IOException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        if (timeout > 0) {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).setSocketTimeout(timeout).build();
            httpPost.setConfig(requestConfig);
        }
        MultipartEntityBuilder mb = MultipartEntityBuilder.create();
        if (nvps != null && !nvps.isEmpty()) {
            for (NameValuePair nv : nvps) {
                mb.addPart(nv.getName(), new StringBody(nv.getValue(), ContentType.DEFAULT_TEXT.withCharset(DEFAULT_CHARSET)));
            }
        }
        if (files != null && !files.isEmpty()) {
            for (Map.Entry<String, File> item : files.entrySet()) {
                if (item.getValue() == null || !item.getValue().exists()) {
                    continue;
                }
                mb.addPart(item.getKey(), new FileBody(item.getValue()));
            }
        }
        httpPost.setEntity(mb.build());
        return httpClient.execute(httpPost);
    }

    /**
     * GET请求
     *
     * @param url 请求地址
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public static HttpResponse get(String url) throws IOException, URISyntaxException {
        return get(url, null);
    }

    /**
     * GET请求
     *
     * @param url    请求URL
     * @param params 请求参数
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public static HttpResponse get(String url, Map<String, String> params) throws IOException, URISyntaxException {
        return get(url, params, -1);
    }

    /**
     * GET请求
     *
     * @param url     请求URL
     * @param params  请求参数
     * @param timeout 超时时间
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public static HttpResponse get(String url, Map<String, String> params, int timeout) throws IOException, URISyntaxException {
        return get(url, params, timeout, null);
    }

    /**
     * GET请求
     *
     * @param url     请求地址
     * @param params  请求参数
     * @param timeout 超时时间
     * @param referer referer
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     * @throws URISyntaxException
     */
    public static HttpResponse get(String url, Map<String, String> params, int timeout, String referer) throws IOException, URISyntaxException {
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        if (timeout > 0) {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).setSocketTimeout(timeout).build();
            httpGet.setConfig(requestConfig);
        }
        if (params != null && params.size() > 0) {
            URIBuilder builder = new URIBuilder(httpGet.getURI());
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                builder.setParameter(key, value);
            }
            URI uri = builder.build();
            httpGet.setURI(uri);
        }
        if (StringUtils.isNotBlank(referer)) {
            httpGet.addHeader("referer", referer);
        }
        return httpClient.execute(httpGet);
    }

}
